﻿using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows;
using MathematicallySafe.Base;
using MathematicallySafe.HeadCounter.Data.Common;
using HeadCounter.Armourer.Base;
using MathematicallySafe.HeadCounter.Data;
using MathematicallySafe.HeadCounter.Data.Models;
using MathematicallySafe.HeadCounter.Services;
using MathematicallySafe.HeadCounter.ViewModels;
using MathematicallySafe.HeadCounter.Views;
using StructureMap;

namespace MathematicallySafe.HeadCounter
{
    public partial class App : System.Windows.Application
    {
        private void OnStartup(object sender, StartupEventArgs e)
        {
            DispatcherUnhandledException += AppDispatcherUnhandledException;
            AppDomain.CurrentDomain.UnhandledException += UnhandledException;

            EnsureDirectoriesExist();
            InitialiseContainers();

            ObjectFactory.GetInstance<ILog<App>>().Info("HeadCounter started " + DateTime.Now);
            ObjectFactory.GetInstance<IHeadCounterService>().Initialise();

            var view = new HeadCounterView()
                       {
                           ViewModel = new HeadCounterViewModel()
                       };

            view.ViewModel.Initialise();
            view.Show();
        }

        private void EnsureDirectoriesExist()
        {
            if (!Directory.Exists(Constants.XmlDirectory)) Directory.CreateDirectory(Constants.XmlDirectory);
        }

        private void InitialiseContainers()
        {
            ObjectFactory.Initialize(x =>
            {
                x.AddRegistry<HeadCounterRegistry>();
                x.AddRegistry<DataRegistry>();
            });
        }

        private void Application_Exit(object sender, ExitEventArgs e)
        {
            AutoBackup();
            ObjectFactory.GetInstance<ILog<App>>().Info("HeadCounter exited normally " + DateTime.Now);
        }

        private void AutoBackup()
        {
            var backupService = ObjectFactory.GetInstance<IBackupService>();

            backupService.ArchiveLocation = Constants.XmlDirectory;
            backupService.DataLocation = Constants.XmlDirectory;
            backupService.DataWildcard = @"/*.xml";
            backupService.ArchiveName = Constants.MainArchiveName;

            backupService.Backup();
        }


        void UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            try
            {
                var ex = (Exception)e.ExceptionObject;

                var log = ObjectFactory.GetInstance<ILog<App>>();
                log.Fatal("Unhandled exception detected, closing application. Message: " + ex.Message, ex);

                MessageBox.Show("ZOMG! HeadCounter has stopped working.", "Unhandled Error - Closing HeadCounter", MessageBoxButton.OK, MessageBoxImage.Stop);
            }
            finally
            {
                Shutdown(1);
            }
        }

        static void AppDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            var log = ObjectFactory.GetInstance<ILog<App>>();
            log.Fatal("HeadCounter unhandled dispatcher exception. Message: " + e.Exception.Message, e.Exception);

            e.Handled = true;
        }
    }
}